"""
文本操作。

提供中文语义友好的字符串处理函数，包括截取、查找、大小写转换、全角半角转换、空白处理、替换与分割等。
"""


# 调用格式： 〈整数型〉 取文本长度 （文本型 文本数据） - 系统核心支持库->文本操作
# 英文名称：len
# 取文本型数据的长度，不包含结束0。本命令为初级命令。
# 参数<1>的名称为“文本数据”，类型为“文本型（text）”。参数值指定欲检查其长度的文本数据。
#
# 操作系统需求： Windows、Linux

def 取文本长度(文本数据: str) -> int:
    """
    返回字符串长度。

    Args:
        文本数据 (str): 待测字符串。

    Returns:
        int: 字符数。
    """
    return len(文本数据)


# 调用格式： 〈文本型〉 取文本左边 （文本型 欲取其部分的文本，整数型 欲取出字符的数目） - 系统核心支持库->文本操作
# 英文名称：left
# 返回一个文本，其中包含指定文本中从左边算起指定数量的字符。本命令为初级命令。
# 参数<1>的名称为“欲取其部分的文本”，类型为“文本型（text）”。
# 参数<2>的名称为“欲取出字符的数目”，类型为“整数型（int）”。
#
# 操作系统需求： Windows、Linux

def 取文本左边(欲取其部分的文本: str, 欲取出字符的数目: int) -> str:
    """
    从左侧截取指定长度的子串。

    Args:
        欲取其部分的文本 (str): 源字符串。
        欲取出字符的数目 (int): 截取长度，超出长度将被限制到最大值。

    Returns:
        str: 截取结果。
    """
    if 取文本长度(欲取其部分的文本) < 欲取出字符的数目:
        欲取出字符的数目 = 取文本长度(欲取其部分的文本)
    return 欲取其部分的文本[0:欲取出字符的数目]


# 调用格式： 〈文本型〉 取文本右边 （文本型 欲取其部分的文本，整数型 欲取出字符的数目） - 系统核心支持库->文本操作
# 英文名称：right
# 返回一个文本，其中包含指定文本中从右边算起指定数量的字符。本命令为初级命令。
# 参数<1>的名称为“欲取其部分的文本”，类型为“文本型（text）”。
# 参数<2>的名称为“欲取出字符的数目”，类型为“整数型（int）”。
#
# 操作系统需求： Windows、Linux

def 取文本右边(欲取其部分的文本: str, 欲取出字符的数目: int) -> str:
    """
    从右侧截取指定长度的子串。

    Args:
        欲取其部分的文本 (str): 源字符串。
        欲取出字符的数目 (int): 截取长度，超出长度将被限制到最大值。

    Returns:
        str: 截取结果。
    """
    l = 取文本长度(欲取其部分的文本)
    lpos = l - 欲取出字符的数目
    if lpos < 0:
        lpos = 0
    return 欲取其部分的文本[lpos:l]


# 调用格式： 〈文本型〉 取文本中间 （文本型 欲取其部分的文本，整数型 起始取出位置，整数型 欲取出字符的数目） - 系统核心支持库->文本操作
# 英文名称：mid
# 返回一个文本，其中包含指定文本中从指定位置算起指定数量的字符。本命令为初级命令。
# 参数<1>的名称为“欲取其部分的文本”，类型为“文本型（text）”。
# 参数<2>的名称为“起始取出位置”，类型为“整数型（int）”。1为首位置，2为第2个位置，如此类推。
# 参数<3>的名称为“欲取出字符的数目”，类型为“整数型（int）”。
#
# 操作系统需求： Windows、Linux

def 取文本中间(欲取其部分的文本, 起始取出位置, 欲取出字符的数目):
    """
    从指定起始位置截取固定长度的子串。

    注意：本函数使用 Python 切片语义，index 从 0 开始。

    Args:
        欲取其部分的文本 (str): 源字符串。
        起始取出位置 (int): 起始索引（0 基）。
        欲取出字符的数目 (int): 截取长度。

    Returns:
        str: 截取结果。
    """
    欲取出字符的数目 = 起始取出位置 + 欲取出字符的数目
    if 取文本长度(欲取其部分的文本) < 欲取出字符的数目:
        欲取出字符的数目 = 取文本长度(欲取其部分的文本)
    return 欲取其部分的文本[起始取出位置: 欲取出字符的数目]


# 调用格式： 〈文本型〉 字符 （字节型 欲取其字符的字符代码） - 系统核心支持库->文本操作
# 英文名称：chr
# 返回一个文本，其中包含有与指定字符代码相关的字符。本命令为初级命令。
# 参数<1>的名称为“欲取其字符的字符代码”，类型为“字节型（byte）”。
#
# 操作系统需求： Windows、Linux

def 字符(字节型: bytes) -> str:
    """
    将 Unicode 码点转换为字符。

    Args:
        字节型 (int): 码点数值，例如 65 -> "A"。

    Returns:
        str: 单个字符。
    """
    return chr(字节型)


# 调用格式： 〈整数型〉 取代码 （文本型 欲取字符代码的文本，［整数型 欲取其代码的字符位置］） - 系统核心支持库->文本操作
# 英文名称：asc
# 返回文本中指定位置处字符的代码。如果指定位置超出文本长度，返回0。本命令为初级命令。
# 参数<1>的名称为“欲取字符代码的文本”，类型为“文本型（text）”。
# 参数<2>的名称为“欲取其代码的字符位置”，类型为“整数型（int）”，可以被省略。1为首位置，2为第2个位置，如此类推。如果本参数被省略，默认为首位置。
#
# 操作系统需求： Windows、Linux

def 取代码(欲取字符代码的文本: str) -> int:
    """
    返回字符串第一个字符的 Unicode 码点。

    Args:
        欲取字符代码的文本 (str): 字符串。

    Returns:
        int: 码点；若为空串则返回 0。
    """
    for item in 欲取字符代码的文本:
        return ord(item)
    return 0


# 调用格式： 〈整数型〉 寻找文本 （文本型 被搜寻的文本，文本型 欲寻找的文本，［整数型 起始搜寻位置］，逻辑型 是否不区分大小写） - 系统核心支持库->文本操作
# 英文名称：InStr
# 返回一个整数值，指定一文本在另一文本中最先出现的位置，位置值从 1 开始。如果未找到，返回-1。本命令为初级命令。
# 参数<1>的名称为“被搜寻的文本”，类型为“文本型（text）”。
# 参数<2>的名称为“欲寻找的文本”，类型为“文本型（text）”。
# 参数<3>的名称为“起始搜寻位置”，类型为“整数型（int）”，可以被省略。位置值从 1 开始。如果本参数被省略，默认为 1 。
# 参数<4>的名称为“是否不区分大小写”，类型为“逻辑型（bool）”，初始值为“假”。为真不区分大小写，为假区分。
#
# 操作系统需求： Windows、Linux
# 找不到返回-1

def 寻找文本(被搜寻的文本: str, 欲寻找的文本: str, 起始搜寻位置=None, 结束的位置=None) -> int:
    """
    查找子串首次出现的位置。

    Python 语义：等价于 str.find，找不到返回 -1。

    Args:
        被搜寻的文本 (str): 源字符串。
        欲寻找的文本 (str): 子串。
        起始搜寻位置 (int, 可选): 起始索引，默认 None。
        结束的位置 (int, 可选): 结束索引（开区间），默认 None。

    Returns:
        int: 索引位置，若找不到则为 -1。
    """
    try:
        result = 被搜寻的文本.find(欲寻找的文本, 起始搜寻位置, 结束的位置)
    except:
        result = -1
    return result


def 倒找文本(被搜寻的文本: str, 欲寻找的文本: str, 起始搜寻位置=None, 结束的位置=None) -> int:
    """
    反向查找子串首次出现的位置。

    Args:
        被搜寻的文本 (str): 源字符串。
        欲寻找的文本 (str): 子串。
        起始搜寻位置 (int, 可选): 起始索引。
        结束的位置 (int, 可选): 结束索引（开区间）。

    Returns:
        int: 索引位置，若找不到则为 -1。
    """
    return 被搜寻的文本.rfind(欲寻找的文本, 起始搜寻位置, 结束的位置)


# 调用格式： 〈文本型〉 到大写 （文本型 欲变换的文本） - 系统核心支持库->文本操作
# 英文名称：UCase
# 将文本中的小写英文字母变换为大写，返回变换后的结果文本。本命令为初级命令。
# 参数<1>的名称为“欲变换的文本”，类型为“文本型（text）”。
#
# 操作系统需求： Windows、Linux

def 到大写(欲变换的文本: str) -> str:
    """将字符串转换为大写。"""
    return 欲变换的文本.upper()



def 到小写(欲变换的文本: str) -> str:
    """将字符串转换为小写（大小写不敏感场景可考虑 casefold）。"""
    return 欲变换的文本.casefold()



def 到全角(欲变换的文本: str) -> str:
    """
    将半角字符转换为全角字符。

    Args:
        欲变换的文本 (str): 源字符串。

    Returns:
        str: 转换后的字符串。
    """
    rstring = ""
    for uchar in 欲变换的文本:
        inside_code = ord(uchar)
        if inside_code == 32:  # 半角空格直接转化
            inside_code = 12288
        elif inside_code >= 32 and inside_code <= 126:  # 半角字符（除空格）根据关系转化
            inside_code += 65248

        rstring += chr(inside_code)
    return rstring



def 到半角(欲变换的文本: str) -> str:
    """
    全角转半角。

    Args:
        欲变换的文本 (str): 源字符串。

    Returns:
        str: 转换后的字符串。
    """
    ss = []
    for s in 欲变换的文本:
        rstring = ""
        for uchar in s:
            inside_code = ord(uchar)
            if inside_code == 12288:  # 全角空格直接转换
                inside_code = 32
            elif inside_code >= 65281 and inside_code <= 65374:
                # 全角字符（除空格）根据关系转化
                inside_code -= 65248

            rstring += chr(inside_code)

        ss.append(rstring)
    return ''.join(ss)


# 调用格式： 〈文本型〉 删首空 （文本型 欲删除空格的文本） - 系统核心支持库->文本操作
# 英文名称：LTrim
# 返回一个文本，其中包含被删除了首部全角或半角空格的指定文本。本命令为初级命令。
# 参数<1>的名称为“欲删除空格的文本”，类型为“文本型（text）”。
#
# 操作系统需求： Windows、Linux

def 删首空(欲删除空格的文本: str) -> str:
    """删除字符串左侧的空白字符。"""
    return 欲删除空格的文本.lstrip()



def 删尾空(欲删除空格的文本: str) -> str:
    """删除字符串右侧的空白字符。"""
    return 欲删除空格的文本.rstrip()



def 删首尾空(欲删除空格的文本: str) -> str:
    """删除字符串两侧的空白字符。"""
    return 删尾空(删首空(欲删除空格的文本))



def 删全部空(欲删除空格的文本: str) -> str:
    """删除字符串中所有半角空格。"""
    return 欲删除空格的文本.replace(" ", "")


# 调用格式： 〈文本型〉 子文本替换 （文本型 欲被替换的文本，文本型 欲被替换的子文本，［文本型 用作替换的子文本］，［整数型 进行替换的起始位置］，［整数型 替换进行的次数］，逻辑型 是否区分大小写） - 系统核心支持库->文本操作
# 英文名称：RpSubText
# 返回一个文本，该文本中指定的子文本已被替换成另一子文本，并且替换发生的次数也是被指定的。本命令为初级命令。
# 参数<1>的名称为“欲被替换的文本”，类型为“文本型（text）”。
# 参数<2>的名称为“欲被替换的子文本”，类型为“文本型（text）”。
# 参数<3>的名称为“用作替换的子文本”，类型为“文本型（text）”，可以被省略。如果本参数被省略，默认为空文本。
# 参数<4>的名称为“进行替换的起始位置”，类型为“整数型（int）”，可以被省略。参数值指定被替换子文本的起始搜索位置。如果省略，默认从 1 开始。
# 参数<5>的名称为“替换进行的次数”，类型为“整数型（int）”，可以被省略。参数值指定对子文本进行替换的次数。如果省略，默认进行所有可能的替换。
# 参数<6>的名称为“是否区分大小写”，类型为“逻辑型（bool）”，初始值为“真”。为真区分大小写，为假不区分。
#
# 操作系统需求： Windows、Linux

def 子文本替换(欲被替换的文本: str, 欲被替换的子文本: str, 用作替换的子文本: str, 替换进行的次数=-1) -> str:
    """
    将字符串中的子串替换为新的内容。

    Args:
        欲被替换的文本 (str): 源字符串。
        欲被替换的子文本 (str): 目标子串，若为空串直接返回源字符串。
        用作替换的子文本 (str): 新子串。
        替换进行的次数 (int, 可选): 替换次数，默认 -1 表示替换全部。

    Returns:
        str: 替换后的结果。
    """
    if (欲被替换的子文本 == ""):
        return 欲被替换的文本
    return 欲被替换的文本.replace(欲被替换的子文本, 用作替换的子文本, 替换进行的次数)


# 调用格式： 〈文本型〉 取空白文本 （整数型 重复次数） - 系统核心支持库->文本操作
# 英文名称：space
# 返回具有指定数目半角空格的文本。本命令为初级命令。
# 参数<1>的名称为“重复次数”，类型为“整数型（int）”。
#
# 操作系统需求： Windows、Linux

def 取空白文本(重复次数: int) -> str:
    """返回指定数量的半角空格。"""
    return 取重复文本(重复次数, " ")


# 调用格式： 〈文本型〉 取重复文本 （整数型 重复次数，文本型 待重复文本） - 系统核心支持库->文本操作
# 英文名称：string
# 返回一个文本，其中包含指定次数的文本重复结果。本命令为初级命令。
# 参数<1>的名称为“重复次数”，类型为“整数型（int）”。
# 参数<2>的名称为“待重复文本”，类型为“文本型（text）”。该文本将用于建立返回的文本。如果为空，将返回一个空文本。
#
# 操作系统需求： Windows、Linux

def 取重复文本(重复次数: int, 待重复文本: str) -> str:
    """
    将文本重复指定次数并拼接。

    Args:
        重复次数 (int): 重复次数，>= 0。
        待重复文本 (str): 被重复的文本。

    Returns:
        str: 拼接结果。
    """
    str = ""
    for _ in range(重复次数):
        str = str + 待重复文本
    return str


# 调用格式： 〈文本型数组〉 分割文本 （文本型 待分割文本，［文本型 用作分割的文本］，［整数型 要返回的子文本数目］） - 系统核心支持库->文本操作
# 英文名称：split
# 将指定文本进行分割，返回分割后的一维文本数组。本命令为初级命令。
# 参数<1>的名称为“待分割文本”，类型为“文本型（text）”。如果参数值是一个长度为零的文本，则返回一个空数组，即没有任何成员的数组。
# 参数<2>的名称为“用作分割的文本”，类型为“文本型（text）”，可以被省略。参数值用于标识子文本边界。如果被省略，则默认使用半角逗号字符作为分隔符。如果是一个长度为零的文本，则返回的数组仅包含一个成员，即完整的“待分割文本”。
# 参数<3>的名称为“要返回的子文本数目”，类型为“整数型（int）”，可以被省略。如果被省略，则默认返回所有的子文本。
#
# 操作系统需求： Windows、Linux

def 分割文本(待分割文本: str, 用作分割的文本: str = ",", 要返回的子文本数目: int = -1) -> dict:
    """
    按分隔符拆分字符串。

    Args:
        待分割文本 (str): 源字符串。
        用作分割的文本 (str, 可选): 分隔符，默认逗号。
        要返回的子文本数目 (int, 可选): 最多分割次数，-1 表示无限制。

    Returns:
        list[str]: 子串列表。
    """
    return 待分割文本.split(用作分割的文本, 要返回的子文本数目)
